unit RclExtendedProperties;

interface

uses
  Contnrs,
  RclString, RclProperties;

type
  TExtendedProperties = class(TProperties)
  private
    subProperties: TObjectList;
    function expandValue(Value: string): string;
  public
    destructor Destroy; override;
    function containsKey(aKey: string): Boolean;
    function GetProperty(const AKey, ADefaultValue: string): string; overload;
      override;
    function getSubset(prefix: string): TExtendedProperties; overload;
    function getSubset(prefix, newPrefix: string): TExtendedProperties; overload;
  end;

implementation

uses
  RclStr;

destructor TExtendedProperties.Destroy;
begin
  if subProperties <> nil then
    subProperties.Free;
  subProperties := nil;
  inherited;
end;

function TExtendedProperties.containsKey(aKey: string): Boolean;
begin
  Result := FValues.IndexOf(AKey) >= 0;
end;

function TExtendedProperties.expandValue(Value: string): string;
var
  p1, p2: Integer;
  paramName,
  paramValue: string;
begin
  Result := Value;
  if (Value = '') or (Length(Value) < 4) then
    Exit;
    
  p1 := Str.Find('${', Result); //$NON-NLS-1$
  p2 := Str.Find('}', Result, 2); //$NON-NLS-1$
  while ((p1 >= 1) and (p2 > p1)) do
  begin
    paramName := Str.SubString(Result, p1 + 2, p2 - p1 - 2);
    paramValue := getProperty(paramName);
    if (paramValue <> '') then
    begin
      Str.Replace(Result, Copy(Result, p1, p2), paramValue);
      p1 := p1 + Length(paramValue);
    end else
      p1 := p2 + 1;

    p1 := Str.Find('${', Result, p1);
    p2 := Str.Find('}', Result, p1 + 2);
  end;
end;

function TExtendedProperties.GetProperty(const AKey, ADefaultValue: string):
  string;
begin
  Result := inherited GetProperty(AKey, ADefaultValue);
  Result := expandValue(Result);
end;

function TExtendedProperties.getSubset(prefix: string): TExtendedProperties;
begin
  Result := getSubset(prefix, '');
end;

function TExtendedProperties.getSubset(prefix, newPrefix: string):
  TExtendedProperties;
var
  i: Integer;
begin
  if subProperties = nil then
    subProperties := TObjectList.Create(True);

  Result := TExtendedProperties.Create;
  for i := 0 to FValues.Count - 1 do
    if (StartsStr(prefix, FValues[i])) then
      Result.FValues.AddObject(FValues[i], TString.Create(GetProperty(FValues[i])));
  subProperties.Add(result);
end;

end.

